home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / glibc108.zip / glibc108 / inet / res_debug.c < prev    next >
C/C++ Source or Header  |  1993-05-19  |  17KB  |  748 lines

  1. /*
  2.  * ++Copyright++ 1985, 1990
  3.  * -
  4.  * Copyright (c) 1985, 1990 Regents of the University of California.
  5.  * All rights reserved.
  6.  * 
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  * 1. Redistributions of source code must retain the above copyright
  11.  *    notice, this list of conditions and the following disclaimer.
  12.  * 2. Redistributions in binary form must reproduce the above copyright
  13.  *    notice, this list of conditions and the following disclaimer in the
  14.  *    documentation and/or other materials provided with the distribution.
  15.  * 3. All advertising materials mentioning features or use of this software
  16.  *    must display the following acknowledgement:
  17.  *     This product includes software developed by the University of
  18.  *     California, Berkeley and its contributors.
  19.  * 4. Neither the name of the University nor the names of its contributors
  20.  *    may be used to endorse or promote products derived from this software
  21.  *    without specific prior written permission.
  22.  * 
  23.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  24.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  25.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  26.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  27.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  28.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  29.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  30.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  31.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  32.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  33.  * SUCH DAMAGE.
  34.  * -
  35.  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
  36.  * 
  37.  * Permission to use, copy, modify, and distribute this software for any
  38.  * purpose with or without fee is hereby granted, provided that the above
  39.  * copyright notice and this permission notice appear in all copies, and that
  40.  * the name of Digital Equipment Corporation not be used in advertising or
  41.  * publicity pertaining to distribution of the document or software without
  42.  * specific, written prior permission.
  43.  * 
  44.  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
  45.  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
  46.  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
  47.  * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  48.  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  49.  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
  50.  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  51.  * SOFTWARE.
  52.  * -
  53.  * --Copyright--
  54.  */
  55.  
  56. #if defined(LIBC_SCCS) && !defined(lint)
  57. static char sccsid[] = "@(#)res_debug.c    5.36 (Berkeley) 3/6/91";
  58. static char rcsid[] = "$Id: res_debug.c,v 4.9.1.2 1993/05/17 10:00:01 vixie Exp $";
  59. #endif /* LIBC_SCCS and not lint */
  60.  
  61. #include <sys/param.h>
  62. #include <netinet/in.h>
  63. #include <arpa/inet.h>
  64. #include <arpa/nameser.h>
  65. #include <resolv.h>
  66. #include <stdio.h>
  67. #include "../conf/portability.h"
  68.  
  69. void __fp_query();
  70. char *__p_class(), *__p_time(), *__p_type();
  71. char *p_cdname(), *p_fqname(), *p_rr();
  72. static char *p_option __P((u_int32_t));
  73.  
  74. char *_res_opcodes[] = {
  75.     "QUERY",
  76.     "IQUERY",
  77.     "CQUERYM",
  78.     "CQUERYU",
  79.     "4",
  80.     "5",
  81.     "6",
  82.     "7",
  83.     "8",
  84.     "UPDATEA",
  85.     "UPDATED",
  86.     "UPDATEDA",
  87.     "UPDATEM",
  88.     "UPDATEMA",
  89.     "ZONEINIT",
  90.     "ZONEREF",
  91. };
  92.  
  93. char *_res_resultcodes[] = {
  94.     "NOERROR",
  95.     "FORMERR",
  96.     "SERVFAIL",
  97.     "NXDOMAIN",
  98.     "NOTIMP",
  99.     "REFUSED",
  100.     "6",
  101.     "7",
  102.     "8",
  103.     "9",
  104.     "10",
  105.     "11",
  106.     "12",
  107.     "13",
  108.     "14",
  109.     "NOCHANGE",
  110. };
  111.  
  112. static char retbuf[16];
  113.  
  114. static char *
  115. dewks(wks)
  116.     int wks;
  117. {
  118.     switch (wks) {
  119.     case 5: return("rje");
  120.     case 7: return("echo");
  121.     case 9: return("discard");
  122.     case 11: return("systat");
  123.     case 13: return("daytime");
  124.     case 15: return("netstat");
  125.     case 17: return("qotd");
  126.     case 19: return("chargen");
  127.     case 20: return("ftp-data");
  128.     case 21: return("ftp");
  129.     case 23: return("telnet");
  130.     case 25: return("smtp");
  131.     case 37: return("time");
  132.     case 39: return("rlp");
  133.     case 42: return("name");
  134.     case 43: return("whois");
  135.     case 53: return("domain");
  136.     case 57: return("apts");
  137.     case 59: return("apfs");
  138.     case 67: return("bootps");
  139.     case 68: return("bootpc");
  140.     case 69: return("tftp");
  141.     case 77: return("rje");
  142.     case 79: return("finger");
  143.     case 87: return("link");
  144.     case 95: return("supdup");
  145.     case 100: return("newacct");
  146.     case 101: return("hostnames");
  147.     case 102: return("iso-tsap");
  148.     case 103: return("x400");
  149.     case 104: return("x400-snd");
  150.     case 105: return("csnet-ns");
  151.     case 109: return("pop-2");
  152.     case 111: return("sunrpc");
  153.     case 113: return("auth");
  154.     case 115: return("sftp");
  155.     case 117: return("uucp-path");
  156.     case 119: return("nntp");
  157.     case 121: return("erpc");
  158.     case 123: return("ntp");
  159.     case 133: return("statsrv");
  160.     case 136: return("profile");
  161.     case 144: return("NeWS");
  162.     case 161: return("snmp");
  163.     case 162: return("snmp-trap");
  164.     case 170: return("print-srv");
  165.     default: (void) sprintf(retbuf, "%d", wks); return(retbuf);
  166.     }
  167. }
  168.  
  169. static char *
  170. deproto(protonum)
  171.     int protonum;
  172. {
  173.     switch (protonum) {
  174.     case 1: return("icmp");
  175.     case 2: return("igmp");
  176.     case 3: return("ggp");
  177.     case 5: return("st");
  178.     case 6: return("tcp");
  179.     case 7: return("ucl");
  180.     case 8: return("egp");
  181.     case 9: return("igp");
  182.     case 11: return("nvp-II");
  183.     case 12: return("pup");
  184.     case 16: return("chaos");
  185.     case 17: return("udp");
  186.     default: (void) sprintf(retbuf, "%d", protonum); return(retbuf);
  187.     }
  188. }
  189.  
  190. static char *
  191. do_rrset(msg, cp, cnt, pflag, file, hs)
  192.     int cnt, pflag;
  193.     char *cp,*msg, *hs;
  194.     FILE *file;
  195. {
  196.     int n;
  197.     char *t1, *t2, *list[100],**tt;
  198.     int sflag;
  199.     /*
  200.      * Print  answer records
  201.      */
  202.     sflag = (_res.pfcode & pflag);
  203.     if (n = ntohs(cnt)) {
  204.         *list=NULL;
  205.         if ((!_res.pfcode) || ((sflag) && (_res.pfcode & RES_PRF_HEAD1)))
  206.             fprintf(file, hs);
  207.         while (--n >= 0) {
  208.             cp = p_rr(cp, msg, file);
  209.             if ((cp-msg) > PACKETSZ)
  210.                 return (NULL);
  211.         }
  212.         if ((!_res.pfcode) || ((sflag) && (_res.pfcode & RES_PRF_HEAD1)))
  213.             putc('\n', file);
  214.     }
  215.     return(cp);
  216. }
  217.  
  218. __p_query(msg)
  219.     char *msg;
  220. {
  221.     __fp_query(msg, stdout);
  222. }
  223.  
  224. /*
  225.  * Print the current options.
  226.  * This is intended to be primarily a debugging routine.
  227.  */
  228. void
  229. __fp_resstat(statp, file)
  230.     struct __res_state *statp;
  231.     FILE *file;
  232. {
  233.     int bit;
  234.  
  235.     fprintf(file, ";; res options:");
  236.     if (!statp)
  237.         statp = &_res;
  238.     for (bit = 0;  bit < 32;  bit++) {    /* XXX 32 - bad assumption! */
  239.         if (statp->options & (1<<bit))
  240.             fprintf(file, " %s", p_option(1<<bit));
  241.     }
  242.     putc('\n', file);
  243. }
  244.  
  245. /*
  246.  * Print the contents of a query.
  247.  * This is intended to be primarily a debugging routine.
  248.  */
  249. void
  250. __fp_query(msg,file)
  251.     char *msg;
  252.     FILE *file;
  253. {
  254.     register char *cp;
  255.     register HEADER *hp;
  256.     register int n;
  257.  
  258.     /*
  259.      * Print header fields.
  260.      */
  261.     hp = (HEADER *)msg;
  262.     cp = msg + sizeof(HEADER);
  263.     if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX) || hp->rcode) {
  264.         fprintf(file,";; ->>HEADER<<- opcode: %s, status: %s, id: %d",
  265.             _res_opcodes[hp->opcode],
  266.             _res_resultcodes[hp->rcode],
  267.             ntohs(hp->id));
  268.         putc('\n', file);
  269.     }
  270.     putc(';', file);
  271.     if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD2)) {
  272.         fprintf(file,"; flags:");
  273.         if (hp->qr)
  274.             fprintf(file," qr");
  275.         if (hp->aa)
  276.             fprintf(file," aa");
  277.         if (hp->tc)
  278.             fprintf(file," tc");
  279.         if (hp->rd)
  280.             fprintf(file," rd");
  281.         if (hp->ra)
  282.             fprintf(file," ra");
  283.         if (hp->pr)
  284.             fprintf(file," pr");
  285.     }
  286.     if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD1)) {
  287.         fprintf(file,"; Ques: %d", ntohs(hp->qdcount));
  288.         fprintf(file,", Ans: %d", ntohs(hp->ancount));
  289.         fprintf(file,", Auth: %d", ntohs(hp->nscount));
  290.         fprintf(file,", Addit: %d\n", ntohs(hp->arcount));
  291.     }
  292. #if 0
  293.     if (_res.pfcode & (RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1)) {
  294.         putc('\n',file);
  295.     }
  296. #endif
  297.     /*
  298.      * Print question records.
  299.      */
  300.     if (n = ntohs(hp->qdcount)) {
  301.         if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
  302.             fprintf(file,";; QUESTIONS:\n");
  303.         while (--n >= 0) {
  304.             fprintf(file,";;\t");
  305.             cp = p_cdname(cp, msg, file);
  306.             if (cp == NULL)
  307.                 return;
  308.             if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
  309.                 fprintf(file, ", type = %s",
  310.                     __p_type(_getshort(cp)));
  311.             cp += sizeof(u_short);
  312.             if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
  313.                 fprintf(file, ", class = %s\n\n",
  314.                     __p_class(_getshort(cp)));
  315.             cp += sizeof(u_short);
  316.         }
  317.     }
  318.     /*
  319.      * Print authoritative answer records
  320.      */
  321.     cp = do_rrset(msg, cp, hp->ancount, RES_PRF_ANS, file,
  322.               ";; ANSWERS:\n");
  323.     if (cp == NULL)
  324.         return;
  325.  
  326.     /*
  327.      * print name server records
  328.      */
  329.     cp = do_rrset(msg, cp, hp->nscount, RES_PRF_AUTH, file,
  330.               ";; AUTHORITY RECORDS:\n");
  331.     if (!cp)
  332.         return;
  333.  
  334.     /*
  335.      * print additional records
  336.      */
  337.     cp = do_rrset(msg, cp, hp->arcount, RES_PRF_ADD, file,
  338.               ";; ADDITIONAL RECORDS:\n");
  339.     if (!cp)
  340.         return;
  341. }
  342.  
  343. char *
  344. p_cdname(cp, msg, file)
  345.     char *cp, *msg;
  346.     FILE *file;
  347. {
  348.     char name[MAXDNAME];
  349.     int n;
  350.  
  351.     if ((n = dn_expand((u_char *)msg, (u_char *)msg + 512, (u_char *)cp,
  352.         (u_char *)name, sizeof(name))) < 0)
  353.         return (NULL);
  354.     if (name[0] == '\0') {
  355.         putc('.', file);
  356.     } else {
  357.         fputs(name, file);
  358.     }
  359.     return (cp + n);
  360. }
  361.  
  362. char *
  363. p_fqname(cp, msg, file)
  364.     char *cp, *msg;
  365.     FILE *file;
  366. {
  367.     char name[MAXDNAME];
  368.     int n, len;
  369.  
  370.     if ((n = dn_expand((u_char *)msg, (u_char *)msg + 512, (u_char *)cp,
  371.         (u_char *)name, sizeof(name))) < 0)
  372.         return (NULL);
  373.     if (name[0] == '\0') {
  374.         putc('.', file);
  375.     } else {
  376.         fputs(name, file);
  377.         if (name[strlen(name) - 1] != '.')
  378.             putc('.', file);
  379.     }
  380.     return (cp + n);
  381. }
  382.  
  383.  
  384.  
  385. /*
  386.  * Print resource record fields in human readable form.
  387.  */
  388. char *
  389. p_rr(cp, msg, file)
  390.     char *cp, *msg;
  391.     FILE *file;
  392. {
  393.     int type, class, dlen, n, c;
  394.     struct in_addr inaddr;
  395.     char *cp1, *cp2;
  396.     u_int32_t tmpttl, t;
  397.     int lcnt;
  398.  
  399.     if ((cp = p_fqname(cp, msg, file)) == NULL)
  400.         return (NULL);            /* compression error */
  401.     type = _getshort(cp);
  402.     cp += sizeof(u_short);
  403.     class = _getshort(cp);
  404.     cp += sizeof(u_short);
  405.     tmpttl = _getlong(cp);
  406.     cp += sizeof(u_int32_t);
  407.     dlen = _getshort(cp);
  408.     cp += sizeof(u_short);
  409.     cp1 = cp;
  410.     if ((!_res.pfcode) || (_res.pfcode & RES_PRF_TTLID))
  411.         fprintf(file, "\t%lu", tmpttl);
  412.     if ((!_res.pfcode) || (_res.pfcode & RES_PRF_CLASS))
  413.         fprintf(file, "\t%s", __p_class(class));
  414.     fprintf(file, "\t%s", __p_type(type));
  415.     /*
  416.      * Print type specific data, if appropriate
  417.      */
  418.     switch (type) {
  419.     case T_A:
  420.         switch (class) {
  421.         case C_IN:
  422.         case C_HS:
  423.             bcopy(cp, (char *)&inaddr, sizeof(inaddr));
  424.             if (dlen == 4) {
  425.                 fprintf(file,"\t%s", inet_ntoa(inaddr));
  426.                 cp += dlen;
  427.             } else if (dlen == 7) {
  428.                 char *address;
  429.                 u_char protocol;
  430.                 u_short port;
  431.  
  432.                 address = inet_ntoa(inaddr);
  433.                 cp += sizeof(inaddr);
  434.                 protocol = *(u_char*)cp;
  435.                 cp += sizeof(u_char);
  436.                 port = _getshort(cp);
  437.                 cp += sizeof(u_short);
  438.                 fprintf(file, "\t%s\t; proto %d, port %d",
  439.                     address, protocol, port);
  440.             }
  441.             break;
  442.         default:
  443.             cp += dlen;
  444.         }
  445.         break;
  446.     case T_CNAME:
  447.     case T_MB:
  448.     case T_MG:
  449.     case T_MR:
  450.     case T_NS:
  451.     case T_PTR:
  452.         putc('\t', file);
  453.         cp = p_fqname(cp, msg, file);
  454.         break;
  455.  
  456.     case T_HINFO:
  457.         if (n = *cp++) {
  458.             fprintf(file,"\t%.*s", n, cp);
  459.             cp += n;
  460.         }
  461.         if (n = *cp++) {
  462.             fprintf(file,"\t%.*s", n, cp);
  463.             cp += n;
  464.         }
  465.         break;
  466.  
  467.     case T_SOA:
  468.         putc('\t', file);
  469.         cp = p_fqname(cp, msg, file);    /* origin */
  470.         putc(' ', file);
  471.         cp = p_fqname(cp, msg, file);    /* mail addr */
  472.         fputs(" (\n", file);
  473.         t = _getlong(cp);  cp += sizeof(u_int32_t);
  474.         fprintf(file,"\t\t\t%lu\t; serial\n", t);
  475.         t = _getlong(cp);  cp += sizeof(u_int32_t);
  476.         fprintf(file,"\t\t\t%lu\t; refresh (%s)\n", t, __p_time(t));
  477.         t = _getlong(cp);  cp += sizeof(u_int32_t);
  478.         fprintf(file,"\t\t\t%lu\t; retry (%s)\n", t, __p_time(t));
  479.         t = _getlong(cp);  cp += sizeof(u_int32_t);
  480.         fprintf(file,"\t\t\t%lu\t; expire (%s)\n", t, __p_time(t));
  481.         t = _getlong(cp);  cp += sizeof(u_int32_t);
  482.         fprintf(file,"\t\t\t%lu )\t; minimum (%s)", t, __p_time(t));
  483.         break;
  484.  
  485.     case T_MX:
  486.         fprintf(file,"\t%d ", _getshort(cp));
  487.         cp += sizeof(u_short);
  488.         cp = p_fqname(cp, msg, file);
  489.         break;
  490.  
  491.       case T_TXT:
  492.         (void) fputs("\t\"", file);
  493.         cp2 = cp1 + dlen;
  494.         while (cp < cp2) {
  495.             if (n = (unsigned char) *cp++) {
  496.                 for (c = n; c > 0 && cp < cp2; c--)
  497.                     if (*cp == '\n') {
  498.                         (void) putc('\\', file);
  499.                         (void) putc(*cp++, file);
  500.                     } else
  501.                         (void) putc(*cp++, file);
  502.             }
  503.         }
  504.         putc('"', file);
  505.           break;
  506.  
  507.     case T_MINFO:
  508.     case T_RP:
  509.         putc('\t', file);
  510.         cp = p_fqname(cp, msg, file);
  511.         putc(' ', file);
  512.         cp = p_fqname(cp, msg, file);
  513.         break;
  514.  
  515.     case T_UINFO:
  516.         putc('\t', file);
  517.         fputs(cp, file);
  518.         cp += dlen;
  519.         break;
  520.  
  521.     case T_UID:
  522.     case T_GID:
  523.         if (dlen == 4) {
  524.             fprintf(file,"\t%u", _getlong(cp));
  525.             cp += sizeof(int32_t);
  526.         }
  527.         break;
  528.  
  529.     case T_WKS:
  530.         if (dlen < sizeof(u_int32_t) + 1)
  531.             break;
  532.         bcopy(cp, (char *)&inaddr, sizeof(inaddr));
  533.         cp += sizeof(u_int32_t);
  534.         fprintf(file, "\t%s %s ( ",
  535.             inet_ntoa(inaddr),
  536.             deproto((int) *cp));
  537.         cp += sizeof(u_char);
  538.         n = 0;
  539.         lcnt = 0;
  540.         while (cp < cp1 + dlen) {
  541.             c = *cp++;
  542.             do {
  543.                  if (c & 0200) {
  544.                     if (lcnt == 0) {
  545.                         fputs("\n\t\t\t", file);
  546.                         lcnt = 5;
  547.                     }
  548.                     fputs(dewks(n), file);
  549.                     putc(' ', file);
  550.                     lcnt--;
  551.                 }
  552.                  c <<= 1;
  553.             } while (++n & 07);
  554.         }
  555.         putc(')', file);
  556.         break;
  557.  
  558. #ifdef ALLOW_T_UNSPEC
  559.     case T_UNSPEC:
  560.         {
  561.             int NumBytes = 8;
  562.             char *DataPtr;
  563.             int i;
  564.  
  565.             if (dlen < NumBytes) NumBytes = dlen;
  566.             fprintf(file, "\tFirst %d bytes of hex data:",
  567.                 NumBytes);
  568.             for (i = 0, DataPtr = cp; i < NumBytes; i++, DataPtr++)
  569.                 fprintf(file, " %x", *DataPtr);
  570.             cp += dlen;
  571.         }
  572.         break;
  573. #endif /* ALLOW_T_UNSPEC */
  574.  
  575.     default:
  576.         fprintf(file,"\t?%d?", type);
  577.         cp += dlen;
  578.     }
  579. #if 0
  580.     fprintf(file, "\t; dlen=%d, ttl %s\n", dlen, __p_time(tmpttl));
  581. #else
  582.     putc('\n', file);
  583. #endif
  584.     if (cp - cp1 != dlen) {
  585.         fprintf(file,";; packet size error (found %d, dlen was %d)\n",
  586.             cp - cp1, dlen);
  587.         cp = NULL;
  588.     }
  589.     return (cp);
  590. }
  591.  
  592. static    char nbuf[40];
  593.  
  594. /*
  595.  * Return a string for the type
  596.  */
  597. char *
  598. __p_type(type)
  599.     int type;
  600. {
  601.     switch (type) {
  602.     case T_A:
  603.         return("A");
  604.     case T_NS:        /* authoritative server */
  605.         return("NS");
  606.     case T_CNAME:        /* canonical name */
  607.         return("CNAME");
  608.     case T_SOA:        /* start of authority zone */
  609.         return("SOA");
  610.     case T_MB:        /* mailbox domain name */
  611.         return("MB");
  612.     case T_MG:        /* mail group member */
  613.         return("MG");
  614.     case T_MR:        /* mail rename name */
  615.         return("MR");
  616.     case T_NULL:        /* null resource record */
  617.         return("NULL");
  618.     case T_WKS:        /* well known service */
  619.         return("WKS");
  620.     case T_PTR:        /* domain name pointer */
  621.         return("PTR");
  622.     case T_HINFO:        /* host information */
  623.         return("HINFO");
  624.     case T_MINFO:        /* mailbox information */
  625.         return("MINFO");
  626.     case T_MX:        /* mail routing info */
  627.         return("MX");
  628.     case T_TXT:        /* text */
  629.         return("TXT");
  630.     case T_RP:        /* responsible person */
  631.         return("RP");
  632.     case T_AXFR:        /* zone transfer */
  633.         return("AXFR");
  634.     case T_MAILB:        /* mail box */
  635.         return("MAILB");
  636.     case T_MAILA:        /* mail address */
  637.         return("MAILA");
  638.     case T_ANY:        /* matches any type */
  639.         return("ANY");
  640.     case T_UINFO:
  641.         return("UINFO");
  642.     case T_UID:
  643.         return("UID");
  644.     case T_GID:
  645.         return("GID");
  646. #ifdef ALLOW_T_UNSPEC
  647.     case T_UNSPEC:
  648.         return("UNSPEC");
  649. #endif /* ALLOW_T_UNSPEC */
  650.     default:
  651.         (void)sprintf(nbuf, "%d", type);
  652.         return(nbuf);
  653.     }
  654. }
  655.  
  656. /*
  657.  * Return a mnemonic for class
  658.  */
  659. char *
  660. __p_class(class)
  661.     int class;
  662. {
  663.  
  664.     switch (class) {
  665.     case C_IN:        /* internet class */
  666.         return("IN");
  667.     case C_HS:        /* hesiod class */
  668.         return("HS");
  669.     case C_ANY:        /* matches any class */
  670.         return("ANY");
  671.     default:
  672.         (void)sprintf(nbuf, "%d", class);
  673.         return(nbuf);
  674.     }
  675. }
  676.  
  677. /*
  678.  * Return a mnemonic for an option
  679.  */
  680. static char *
  681. p_option(option)
  682.     u_int32_t option;
  683. {
  684.     switch (option) {
  685.     case RES_INIT:        return "init";
  686.     case RES_DEBUG:        return "debug";
  687.     case RES_AAONLY:    return "aaonly";
  688.     case RES_USEVC:        return "usevc";
  689.     case RES_PRIMARY:    return "primry";
  690.     case RES_IGNTC:        return "igntc";
  691.     case RES_RECURSE:    return "recurs";
  692.     case RES_DEFNAMES:    return "defnam";
  693.     case RES_STAYOPEN:    return "styopn";
  694.     case RES_DNSRCH:    return "dnsrch";
  695.     default:        sprintf(nbuf, "?0x%x?", option); return nbuf;
  696.     }
  697. }
  698.  
  699. /*
  700.  * Return a mnemonic for a time to live
  701.  */
  702. char *
  703. __p_time(value)
  704.     u_int32_t value;
  705. {
  706.     int secs, mins, hours, days;
  707.     register char *p;
  708.  
  709.     if (value == 0) {
  710.         strcpy(nbuf, "0 secs");
  711.         return(nbuf);
  712.     }
  713.  
  714.     secs = value % 60;
  715.     value /= 60;
  716.     mins = value % 60;
  717.     value /= 60;
  718.     hours = value % 24;
  719.     value /= 24;
  720.     days = value;
  721.     value = 0;
  722.  
  723. #define    PLURALIZE(x)    x, (x == 1) ? "" : "s"
  724.     p = nbuf;
  725.     if (days) {
  726.         (void)sprintf(p, "%d day%s", PLURALIZE(days));
  727.         while (*++p);
  728.     }
  729.     if (hours) {
  730.         if (days)
  731.             *p++ = ' ';
  732.         (void)sprintf(p, "%d hour%s", PLURALIZE(hours));
  733.         while (*++p);
  734.     }
  735.     if (mins) {
  736.         if (days || hours)
  737.             *p++ = ' ';
  738.         (void)sprintf(p, "%d min%s", PLURALIZE(mins));
  739.         while (*++p);
  740.     }
  741.     if (secs || ! (days || hours || mins)) {
  742.         if (days || hours || mins)
  743.             *p++ = ' ';
  744.         (void)sprintf(p, "%d sec%s", PLURALIZE(secs));
  745.     }
  746.     return(nbuf);
  747. }
  748.